package controller

import (
	"danmu/common"
	"danmu/dto"
	"danmu/model"
	"danmu/response"
	"danmu/util"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"golang.org/x/crypto/bcrypt"
	"log"
	"net/http"
)

func Register(ctx *gin.Context) {
	DB :=common.GetDB()
	//获取参数
	type requestRegister struct {
		Name string
		Email string
		Password string
		Code string
	}
	var requestUser requestRegister
	err := ctx.Bind(&requestUser)
	if err != nil{
		response.Response(ctx,http.StatusBadRequest,400,nil,"请求错误")
		return
	}
	name := requestUser.Name
	email := requestUser.Email
	password := requestUser.Password
	code := requestUser.Code
	//name := ctx.PostForm("name")
	//password := ctx.PostForm("password")
	//email := ctx.PostForm("email")

	//数据验证
	if !util.VerifyEmailFormat(email) {
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"邮箱格式有误")
		return
	}
	if len(password) < 6 {
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"密码不能少于六位")
		return
	}
	//邮箱是否存在
	if isEmailExist(DB,email){
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"用户已存在")
		return
	}
	//验证码
	if len(code) != 6 {
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"验证码有误")
		return
	}
	status := VerificationCode(email,code)
	if status == 1{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"验证失败")
		return
	}else if status == -1{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"验证码已失效")
		return
	}
	//如果名称为空，则为随机字符串
	if len(name) == 0{
		name = util.RandomString(10)
	}
	//新建用户
	hasedPassword, err := bcrypt.GenerateFromPassword([]byte(password),bcrypt.DefaultCost)
	if err != nil {
		response.Response(ctx,http.StatusUnprocessableEntity,500,nil,"注册失败")
		return
	}
	newUser :=model.User{
		Name:name,
		Email:email,
		Password:string(hasedPassword),
	}
	DB.Create(&newUser)
	//返回结果
	response.Success(ctx,nil,"注册成功")
}

func Login(ctx *gin.Context)  {
	DB :=common.GetDB()
	//获取参数
	var requestUser = model.User{}
	requestErr := ctx.Bind(&requestUser)
	if requestErr != nil{
		response.Response(ctx,http.StatusBadRequest,400,nil,"请求错误")
		return
	}
	password := requestUser.Password
	email := requestUser.Email
	//数据验证
	if !util.VerifyEmailFormat(email) {
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"邮箱格式有误")
		return
	}
	if len(password) < 6 {
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"密码不能少于六位")
		return
	}
	//判断邮箱是否存在
	var user model.User
	DB.Where("email = ?" ,email).First(&user)
	if user.ID == 0{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"用户不存在")
		return
	}
	//判断密码
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password),[]byte(password)) ; err != nil {
		response.Response(ctx,http.StatusUnprocessableEntity,400,nil,"密码错误")
		return
	}
	//发放token
	token, err := common.ReleaseToken(user)
	if err != nil {
		response.Response(ctx,http.StatusUnprocessableEntity,500,nil,"系统异常")
		log.Printf("token generate error",err)
		return
	}
	//返回数据
	response.Success(ctx,gin.H{"token":token},"登陆成功")
}

func UserInfo(ctx *gin.Context)  {
	user,_ :=ctx.Get("user")
	ctx.JSON(http.StatusOK,gin.H{"code":200,"data":gin.H{"user":dto.ToUserDto(user.(model.User))}})
}

func GetInfoById(ctx *gin.Context){
	DB :=common.GetDB()
	uid := ctx.DefaultQuery("uid", "0")
	if uid == "0" {
		response.Fail(ctx,nil,"用户不存在")
		return
	}
	var userInfo model.User
	DB.First(&userInfo, uid)
	ctx.JSON(http.StatusOK,gin.H{"code":200,"data":gin.H{"user":dto.ToUserDto(userInfo)}})
}


func ModifyInfo(ctx *gin.Context)  {
	DB :=common.GetDB()
	var user model.User
	//获取参数
	var requestUser = model.User{}
	err := ctx.Bind(&requestUser)
	if err != nil{
		response.Response(ctx,http.StatusBadRequest,400,nil,"请求错误")
		return
	}
	name := requestUser.Name
	sign := requestUser.Sign
	if len(name)==0{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"名称不能为空")
		return
	}
	//从上下文中获取用户id
	id,_ :=ctx.Get("id")
	//根据id查找用户
	DB.First(&user, id)
	DB.Model(&user).Updates(model.User{Name: name, Sign: sign})
	response.Success(ctx,nil,"修改成功")
}

func isEmailExist(db *gorm.DB,email string) bool {
	var user model.User
	db.Where("email = ?" ,email).First(&user)
	if user.ID != 0{
		return true
	}
	return false
}
